package core;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import core.db.DBConnectionUtil;
import core.util.CommUtils;
import core.util.Const;
import core.util.DateUtil;
/**
 * 文件上传核心类
 * @author Administrator
 *
 */
public class FileUploadServlet extends HttpServlet {
  private static String path;
  static {
    path =  CommUtils.getPropValByKey("file.upload.dir", "conf");
    File f = new File( path );
    if ( !f.exists() ) {
      f.mkdirs();
    }
  }
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    request.setCharacterEncoding( Const.DEFAULT_CODE );
    DiskFileItemFactory factory = new DiskFileItemFactory();   //获得磁盘文件条目工厂
    /**
     * 原理 它是先存到 暂时存储室，然后在真正写到 对应目录的硬盘上， 
     * 按理来说 当上传一个文件时，其实是上传了两份，第一个是以 .tem 格式的 
     * 然后再将其真正写到 对应目录的硬盘上
     */
    factory.setRepository(new File(path));
    factory.setSizeThreshold(1024*1024) ;  //设置 缓存的大小，当上传文件的容量超过该缓存时，直接放到 暂时存储室
    ServletFileUpload upload = new ServletFileUpload(factory); //高水平的API文件上传处理
    long starttime = System.currentTimeMillis();
    upload.setHeaderEncoding("UTF-8");    
    String moudle = request.getParameter("moudle");
    if ( CommUtils.isNull(moudle) ) {
      moudle = "moudle";
    }
    String filename = "";   
    try {
      List<FileItem> list = (List<FileItem>)upload.parseRequest(request);
      for (FileItem item : list ) {
        String name = item.getFieldName();  //获取表单的属性名字
        String fileName = item.getName();
        if ( CommUtils.isNull(fileName) ) {
          continue;
        }
        if( item.isFormField()) {            //如果获取的 表单信息是普通的 文本 信息
          String value = item.getString() ; //获取用户具体输入的字符串 ，名字起得挺好，因为表单提交过来的是 字符串类型的
          filename = fileName;
        } else {
          String value = item.getName() ;   //获取路径名
          int start = value.lastIndexOf("\\"); //索引到最后一个反斜杠
          int fix = value.lastIndexOf(".");
          if ( fix > start ) {
            filename = value.substring(start+1, value.lastIndexOf(".")) 
             + "_" + DateUtil.parseDate(new Date(), "yyyyMMddHHmmss")
             + value.substring(value.lastIndexOf("."));   //截取 上传文件的 字符串名字，加1是 去掉反斜杠，
         } else {
           filename = value.substring(start+1)  //截取 上传文件的 字符串名字，加1是 去掉反斜杠， 
           + "_" + DateUtil.parseDate(new Date(), "yyyyMMddHHmmss");
         }
        }
        item.write( new File(path+ File.separator,filename) );//第三方提供的
        String files = saveUploadFile(filename, fileName, moudle, path + File.separator+filename);
        //插入数据库
        ajaxMethod(files,  response );
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    doGet(req, resp);
  }
  
  /**
   * ajax方法
   * 
   * @param messages
   * @throws Exception
   */
  public void ajaxMethod(String messages, HttpServletResponse response ){
    PrintWriter out = null;
    try {
      response.setContentType("text/html;charset=UTF-8");
      response.setHeader("Cache-Control", "no-cache");
      response.setCharacterEncoding("UTF-8");
      out = response.getWriter();
      out.print(String.valueOf(messages));
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (out != null) {
        out.flush();
        out.close();
      }
    }
  }
  /**
   * 
   * @param fileName 上传后的文件名
   * @param realName 真实文件名
   * @param module   模块
   * @param fpath    文件路径 
   * @return
   */
  public String saveUploadFile(String fileName, String realName, String module, String fpath) {
    String sql = " insert into upload_file( created, name, fname, module, fpath ) values (?,?,?,?,?)";
    Connection con = null;
    PreparedStatement ps =  null;
    int id = 0;
    try {
      con=DBConnectionUtil.getDBConnection("");
      ps = con.prepareStatement(sql);
      ps.setString(1, DateUtil.parseDate( new Date() ));
      ps.setString(2, realName);
      ps.setString(3, fileName);
      ps.setString(4, module);
      ps.setString(5, fpath);
      ps.executeUpdate();
      ResultSet rs = ps.getGeneratedKeys();
      if ( rs != null && rs.next() ) {
        id = rs.getInt(1);
      }
    } catch (Exception e) {
      e.printStackTrace();
      return new JSONObject().put("state", 1).toString();
    } finally {
      DBConnectionUtil.close(null, ps, con);     
    }
    JSONObject obj = new JSONObject();
    obj.put("state", 0);
    obj.put("fileName", realName);
    obj.put("attachmentId", id);
    return obj.toString();
  }
}
